package com.mycode.abstractFactory04;

import com.mycode.abstractFactory04.resolve.Button;
import com.mycode.abstractFactory04.resolve.SkinFactory;
import com.mycode.abstractFactory04.resolve.SpringSkinFactory;

/**
 * 工厂方式模式通过引入工厂等级结构，解决了简单工厂模式中工厂职责太重的问题，但由于工厂方式模式增加具体的产品就会响应的增加工厂类，
 * 可能会导致系统中存在大量的工厂类，势必会增加系统的开销，此时可以考虑将一些相关的产品组成 产品族
 *
 * 当需要增加新的按钮，不能在符合开闭原则的前提下增加新的组件，增加新组件需要修改 SkinFactory 代码，声明创建新组件的方法，
 * 然后逐个修改具体工厂类，还需要修改客户端，否则无法应用于现有系统，这就是抽象工厂模式最大的缺点
 * 在抽象工厂模式中，增加新的产品族很方柏霓，但是增加新的产品等级结构很麻烦，
 * 主要优点：
 *   1、抽象工厂模式隔离了具体类的生成，客户类不用关心创建细节，这种隔离，更换一个具体工厂变得相对容易，
 *   具体工厂实现了抽象工厂中声明的公共接口，因此只需要改变具体工厂的实例，就可以在某种成都下改变整个系统的行为
 *   2、当一个产品族中的多个对象被设计成一起工作时，能够保证客户端始终只使用同一个产品族中的对象
 *   3、增加新的产品族很方便，无须修改已有系统，符合开闭原则
 * 主要缺点：增加新的产品等级结构麻烦，需要对原有系统进行较大的修改
 * 适用场景：
 *   1、一个系统不应当依赖与产品类实例如何被创建、组合和表达的细节，将对象的创建和使用解耦
 *   2、系统中有多于一个的产品族，而每次只使用其中某一产品族，通过配置文件等方式可以动态改变产品族
 *   3、同一个产品族的产品将在一起使用
 *   4、产品等级结构稳定，设计完成之后，不会向系统中增加新的产品等级结构或者删除已有的产品等级结构
 */
public class Bootstrap {

    public static void main(String[] args) {
        SkinFactory factory = new SpringSkinFactory();
        Button button = factory.createButton();
        button.display();

    }
}
